﻿/*
 * Copyright © 2025−2026 WEI.ZHOU (Willis) (Chengdu). All rights reserved.
 *
 * THIS SOURCE CODE IS PROPRIETARY AND CONFIDENTIAL.
 * It is the exclusive property of WEI.ZHOU (Willis) and may not be
 * used, copied, distributed, or disclosed outside of WEI.ZHOU (Willis)
 * without express written permission.
 *
 * This code is provided to WEI.ZHOU (Willis) under a limited, 
 * non-transferable internal license, and is for use only with the author's 
 * approved purposes. No external license is granted or implied.
 *
 * Any unauthorized use, reproduction, or distribution is strictly prohibited
 * and may result in severe civil and criminal penalties.
 */

using Aore.Core.BaseModels;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Net;

namespace Aore.Core.Filters;

public class GlobalExceptionFilter : IExceptionFilter
{
    private readonly ILogger<GlobalExceptionFilter> _logger;
    private readonly IWebHostEnvironment _env;

    public GlobalExceptionFilter(
        ILogger<GlobalExceptionFilter> logger, 
        IWebHostEnvironment env)
    {
        _logger = logger;
        _env = env;
    }

    public void OnException(ExceptionContext context)
    {
        // 记录异常日志
        _logger.LogError(context.Exception, "全局异常处理：{Message}", context.Exception.Message);

        // 根据异常类型返回不同的状态码和消息
        int statusCode;
        string message;
        object data = null;

        switch (context.Exception)
        {
            case UnauthorizedAccessException _:
                statusCode = (int)HttpStatusCode.Unauthorized;
                message = "未授权访问";
                break;
                
            case NotImplementedException _:
                statusCode = (int)HttpStatusCode.NotImplemented;
                message = "功能未实现";
                break;
                
            case ArgumentException ex:
                statusCode = (int)HttpStatusCode.BadRequest;
                message = ex.Message;
                break;
                
            case KeyNotFoundException _:
                statusCode = (int)HttpStatusCode.NotFound;
                message = "资源不存在";
                break;
                
            case TimeoutException _:
                statusCode = (int)HttpStatusCode.RequestTimeout;
                message = "请求超时";
                break;
                
            default:
                statusCode = (int)HttpStatusCode.InternalServerError;
                message = "服务器内部错误";
                
                // 开发环境返回详细错误信息
                if (_env.IsDevelopment())
                {
                    data = new
                    {
                        ExceptionType = context.Exception.GetType().Name,
                        context.Exception.Message,
                        context.Exception.StackTrace
                    };
                }
                break;
        }

        // 构造返回结果
        var result = new ApiResult()
        {
          Success = false,
          Message = message,
          Code = statusCode.ToString(),
          Context = data
          
        };

        // 处理结果
        context.Result = result;
        context.ExceptionHandled = true; // 标记异常已处理
    }
}